import sys
import socket
import asyncio
import struct
import os
import random
import time

async def coroutine_accept(s):
    while True:
        c,addr = s.accept()
        await coroutine_network(c)
    
async def coroutine_network(c):
    await asyncio.gather(
        asyncio.to_thread(coroutine_recv,c),
        asyncio.to_thread(coroutine_send,c))

def coroutine_recv(c):
    while True:
        try:
            recv_data = c.recv(1024)
            print(recv_data.decode("utf-8"))
        except Exception as e:
            print(e)
            break

def coroutine_send(c):
    while True:
        try:
            send_data = c.send(random._urandom(30))
            print(send_data)
            time.sleep(1)
        except Exception as e:
            print(e)
            break


def main(argv): 
    #udp
    if argv[1]=="1":
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
        s.bind(("0.0.0.0",int(argv[3])))
        if 0:#broadcast
            s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
            s.setsockopt(
                socket.IPPROTO_IP,
                socket.IP_ADD_MEMBERSHIP,
                socket.inet_aton("226.0.0.70") + socket.inet_aton(argv[2])
            )
        with open(argv[4], "rb") as f:
            while True:
                header = f.read(4)
                if not header: break
                data = f.read(struct.unpack('h', header[2:4])[0])
                s.sendto(header+data, (argv[2],int(argv[3])))
        recv_data,addr = s.recvfrom(1024)
        print(recv_data.decode("utf-8"),addr)

    #client
    if argv[1]=="2":
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #s.bind(("0.0.0.0",9000))
        s.connect((argv[2],int(argv[3])))
        s.send(bytes([0x55,0xff,0x00,0xaa,0x01,0x00,0x00,0x00,0x21]))
        #s.send("hello".encode("utf-8"))
    #server
    if argv[1]=="3":
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(("0.0.0.0",int(argv[3])))
        s.listen(128)
        asyncio.run(coroutine_accept(s))
    #s.close()

if __name__=="__main__":
    sys.argv=["","3","localhost","9099","D:\\HTCK\\2024\\DFZ\\数据\\#1\\0.dat"]
    main(sys.argv)
    input('input to exit')


#python tcp_udp.py 1 localhost 8000
#python tcp_udp.py 2 localhost 8000
#python tcp_udp.py 3 8000